import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Tab, Tag, Balloon, Nav, Divider } from '@teamix/ui';
import Pagination from 'components/commonPagination';
import {
  Header,
  Body,
  BodyContent,
  OperationBar,
  Content,
  SearchIcon,
  YunxiaoTable,
  SideBar,
  Title,
} from '@alife/devops-ui';
import exceed from 'utils/apimap';
import ListLoading from 'atComponents/ListLoading';
import MrSkeleton from 'components/skeleton/mr';
import BrSkeleton from 'components/skeleton/ul';
import FullPage from 'components/FullPage';
import track, { enterPage, Perf } from 'utils/track';
import debounce from 'lodash.debounce';
import AdvancedSearch from './advancedSearch';
import * as actions from '../actions/index';
import Empty from './empty';
import KEYCODE from 'utils/keycode';
import { ENUM } from 'utils/constants';
import utils from 'utils';
import TextAvatar from '@txdfe/at-text-avatar';
import GroupStatus from './group-status';
import InstanceStatus from './instance-status';
import FlowBtn from './flowBtn';
import intl from '../../../../../../../locale';

const { pathResource } = window.FORCE;
const { ctrlKey, ctrlTxt } = ENUM.getOSKeyMap();
const PAGE_NAME = 'Repo-Pipeline';
let timer;
const tabDataSource = [
  {
    value: (
      <span>
        {intl.get({
          id: 'code-assets.projectPipeline.containers.root.AssemblyLine',
          defaultMessage: '全部流水线',
        })}
      </span>
    ),

    key: 'pipeline',
  },

  {
    value: (
      <span>
        {intl.get({
          id: 'code-assets.projectPipeline.containers.root.BranchOverview',
          defaultMessage: '按分支查看',
        })}
      </span>
    ),

    key: 'branch',
  },
];

class Root extends Component {
  static propTypes = {
    tabKey: PropTypes.string,
    orderKey: PropTypes.string,
    pipelines: PropTypes.arrayOf(PropTypes.object),
    currentPage: PropTypes.number,
    totalData: PropTypes.number,

    getPipelines: PropTypes.func,
    setSearch: PropTypes.func,
    setTabKey: PropTypes.func,
    setOrderKey: PropTypes.func,
  };

  constructor(props) {
    super(props);
    this.onSearch = debounce(this.onSearch, 500);
    this.state = {
      branches: [],
      branches_loading: true,
      checked_branch_name: window.FORCE.pathResource.defaultBranch,
    };
  }

  componentDidMount() {
    this.props.getPipelines(1, 'isDidMount');
    const isTooLarge = utils.isTooLarge(this.props.pageInfo.pathResource);
    if (isTooLarge && document.getElementById('container')) {
      document.getElementById('container').classList.add('has-too-large-tip');
    }
    enterPage(PAGE_NAME, {
      sendPerf: false,
    });

    document.addEventListener('keydown', this.handleKeyCodeEvent);
    this.fetchBranches();
  }

  startTimeInterval = () => {
    if (timer) clearInterval(timer);
    const { currentPage } = this.props;
    if (currentPage !== 1) {
      clearInterval(timer);
      return true;
    }
    timer = setInterval(() => {
      if (document.visibilityState === 'visible') {
        const { tabKey } = this.props;
        if (tabKey === 'branch') {
          this.props.getPipelines(1, 'isBranch', {
            branch_name: window.FORCE.pathResource.defaultBranch,
            noLoading: true,
          });
        } else {
          this.props.getPipelines(1, 'isDidMount', { noLoading: true });
        }
      }
    }, 3000);
    return true;
  };

  fetchBranches = () => {
    this.setState({
      branches_loading: true,
    });

    exceed
      .fetch({
        api: 'projects.all.branches.search',
        params: {
          id: pathResource.id,
        },
      })
      .then((result) => {
        const { defaultBranch } = window.FORCE.pathResource;
        const master = result.filter((v) => v.name === defaultBranch);
        if (master.length) {
          master[0].tag = (
            <Tag size="small" style={{ minWidth: 56, marginLeft: '4px' }}>
              {intl.get({
                id: 'code-assets.projectPipeline.containers.root.DefaultBranch',
                defaultMessage: '默认分支',
              })}
            </Tag>
          );
        }
        const rest = result.filter((v) => v.name && v.name !== defaultBranch);
        this.setState({
          branches: master.concat(rest),
          branches_loading: false,
        });
      });
  };

  handleKeyCodeEvent = (e) => {
    // ctrl + / 进行搜索
    if (e[ctrlKey] && e.keyCode === KEYCODE.SPLIT) {
      document.querySelector('.search-ctrl>button').click();
      document.querySelector('.search-ctrl input').focus();
    }
  };

  componentDidUpdate(prevProps) {
    if (prevProps.repoSize !== this.props.repoSize) {
      const isTooLarge = utils.isTooLarge(this.props.pageInfo.pathResource);
      if (isTooLarge && document.getElementById('container')) {
        document.getElementById('container').classList.add('has-too-large-tip');
      }
    }
  }

  componentWillUnmount() {
    document.removeEventListener('keydown', this.handleKeyCodeEvent);
    if (document.getElementById('container')) {
      document.getElementById('container').classList.remove('has-too-large-tip');
    }
    this.props.resetData();
    timer && clearInterval(timer);
  }

  // 搜索条件
  onSearch = (search) => {
    if (timer) clearInterval(timer);
    track({
      action: 'search_mr',
      page: PAGE_NAME,
    });

    this.props.setSearch(search.trim());
  };

  // 排序
  onPageNoChange = (page) => {
    if (timer) clearInterval(timer);
    this.props.getPipelines(page);
  };

  onPageSizeChange = (pageSize) => {
    if (timer) clearInterval(timer);
    this.props.updateData({
      pageSize,
    });

    this.props.getPipelines(1, undefined, {
      per_page: pageSize,
    });
  };

  // tab切换
  onTabKeySelectChange = (tabKey) => {
    if (timer) clearInterval(timer);
    this.props.setTabKey(tabKey, true);
    if (tabKey === 'branch') {
      this.props.getPipelines(1, 'isBranch', {
        branch_name: window.FORCE.pathResource.defaultBranch,
      });
    } else {
      this.props.getPipelines(1);
    }

    track({
      action: `view_${tabKey}_overview`,
      page: PAGE_NAME,
    });
  };

  // pipeline切换
  onNavClick = (arrKey) => {
    if (timer) clearInterval(timer);
    if (!arrKey || !arrKey.length) return;
    const key = arrKey[0];
    this.setState({
      checked_branch_name: key,
    });

    this.props.getPipelines(1, 'isBranch', { branch_name: key });
  };

  renderList = () => {
    const { pipelines, isLoading, tabKey } = this.props;
    return (
      <>
        {!isLoading ? (
          <>
            <Perf page={PAGE_NAME} />
            <YunxiaoTable
              dataSource={pipelines}
              hasBorder={false}
              emptyContent={
                <div className="nopipeline-text">
                  {intl.get({
                    id: 'code-assets.projectPipeline.containers.root.NoPipelineExecutionRecordsAre',
                    defaultMessage: '暂无流水线执行记录',
                  })}
                </div>
              }
              // hasHeader={false}
              loading={isLoading}
              maxBodyHeight={'initial'}
            >
              {tabKey && tabKey === 'pipeline' ? (
                <YunxiaoTable.Column
                  title={intl.get({
                    id: 'code-assets.projectPipeline.containers.root.PipelineName',
                    defaultMessage: '流水线名称',
                  })}
                  dataIndex="pipeline_name"
                  // className="pipeline-title-col"
                  cell={(value, index, { pipeline_id, pipeline_name }) => {
                    return (
                      <a
                        href={`https://flow.aliyun.com/pipelines/${pipeline_id}/current`}
                        target="_blank"
                        rel="noreferrer"
                        className="pipeline-title-a"
                        onClick={this.startTimeInterval}
                      >
                        {pipeline_name}
                      </a>
                    );
                  }}
                />
              ) : null}
              <YunxiaoTable.Column
                title={intl.get({
                  id: 'code-assets.projectPipeline.containers.root.RecentRunningStatus',
                  defaultMessage: '最近运行状态',
                })}
                dataIndex="build_status"
                // className="pipeline-status-col"
                cell={(
                  _,
                  __,
                  { pipeline_name, pipeline_id, build_id, build_status, flow_inst },
                ) => {
                  if (!flow_inst) {
                    return '-';
                  }
                  const runStatus = flow_inst.status;
                  return (
                    runStatus && (
                      <InstanceStatus
                        number={build_id}
                        status={flow_inst.runningStatus}
                        resultStatus={build_status}
                        pipeline_name={tabKey === 'pipeline' ? '' : pipeline_name}
                        pipeline_id={pipeline_id}
                        startTimeInterval={this.startTimeInterval}
                      />
                    )
                  );
                }}
              />

              <YunxiaoTable.Column
                title={intl.get({
                  id: 'code-assets.projectPipeline.containers.root.LastRunPhase',
                  defaultMessage: '最近运行阶段',
                })}
                dataIndex="flow_inst"
                // className="pipeline-step-col"
                // style={{ width: 224, height: 73 }}
                cell={(_, __, { flow_inst }) => {
                  if (!flow_inst) {
                    return '-';
                  }
                  const runStatus = flow_inst.status;
                  return runStatus && <GroupStatus groups={flow_inst && flow_inst.groups} />;
                }}
              />

              <YunxiaoTable.Column
                title={intl.get({
                  id: 'code-assets.projectPipeline.containers.root.Operator',
                  defaultMessage: '运行人',
                })}
                dataIndex="creator"
                // className="pipeline-owner-col"
                cell={(user) => {
                  if (!user) {
                    return '-';
                  }
                  return (
                    <Balloon.Tooltip
                      type="primary"
                      align="tl"
                      trigger={
                        <span className="text-avatar-outer">
                          <TextAvatar
                            text={user.username}
                            sliceLength="2"
                            size="xs"
                            image={user.avatar_url}
                            style={{ marginRight: 4 }}
                            needAddedText
                          />
                        </span>
                      }
                    >
                      {user.username}
                    </Balloon.Tooltip>
                  );
                }}
              />

              <YunxiaoTable.Column
                title={intl.get({
                  id: 'code-assets.projectPipeline.containers.root.Runtime',
                  defaultMessage: '运行时间',
                })}
                dataIndex="gmt_create"
                // className="pipeline-time-col"
                cell={(value, index, record) => {
                  if (!record.flow_inst) {
                    return '-';
                  }
                  return utils.getBeautyTime(value);
                }}
              />
            </YunxiaoTable>
          </>
        ) : (
          <MrSkeleton style={{ flex: 1 }} />
        )}
      </>
    );
  };

  render() {
    const { branches, checked_branch_name, branches_loading } = this.state;
    const { tabKey, pipelines, projectInfo, isLoading, isDidMount, pageInfo, total, currentPage } =
      this.props;
    const isEmptyProject = pageInfo.pathResource.isEmpty === 'true';
    if (isEmptyProject) {
      return (
        <FullPage>
          <Empty
            projectInfo={projectInfo}
            isEmptyProject
            startTimeInterval={this.startTimeInterval}
          />
        </FullPage>
      );
    }
    if (!isLoading && isDidMount === 'isDidMount' && !pipelines.length && !this.props.search) {
      return (
        <FullPage>
          <Empty projectInfo={projectInfo} startTimeInterval={this.startTimeInterval} />
        </FullPage>
      );
    }

    return (
      <>
        <Header
          title={intl.get({
            id: 'code-assets.projectPipeline.containers.root.AssemblyLine',
            defaultMessage: '流水线',
          })}
          operation={
            <>
              <SearchIcon
                direction="rtl"
                placeholder={intl.get({
                  id: 'code-assets.projectPipeline.containers.root.SearchPipeline',
                  defaultMessage: '搜索流水线',
                })}
                onChange={(value) => {
                  this.onSearch(value);
                }}
                defaultValue={this.props.search}
                className="search-ctrl"
                triggerTooltipProps={{
                  children: (
                    <div>
                      {intl.get({
                        id: 'code-assets.projectPipeline.containers.root.Search',
                        defaultMessage: '搜索',
                      })}
                      <br />
                      {ctrlTxt} + /
                    </div>
                  ),

                  align: 't',
                }}
              />

              <AdvancedSearch
                needBranch={tabKey === 'branch'}
                branch_name={checked_branch_name}
                {...this.props}
              />
              <Divider direction="ver" />
              <FlowBtn projectInfo={projectInfo} startTimeInterval={this.startTimeInterval} />
            </>
          }
        />
        <Body>
          {tabKey === 'branch' ? (
            <SideBar size="small">
              {branches_loading ? (
                <BrSkeleton />
              ) : (
                <Nav selectedKeys={[checked_branch_name]} onSelect={this.onNavClick}>
                  {branches.map((o) => (
                    <Nav.Item key={o.name} className="pipline-branch-nav-item">
                      <Title trigger={<span>{o.name}</span>} align="t">
                        {o.name}
                      </Title>
                      {o.tag ? o.tag : null}
                    </Nav.Item>
                  ))}
                </Nav>
              )}
            </SideBar>
          ) : null}
          <BodyContent>
            {isLoading ? (
              <ListLoading />
            ) : (
              <>
                <OperationBar>
                  <Tab onChange={this.onTabKeySelectChange} activeKey={tabKey} animation={false}>
                    {tabDataSource.map((item) => (
                      <Tab.Item title={item.value} key={item.key} badge={item.badge} />
                    ))}
                  </Tab>
                </OperationBar>
                <Content>{this.renderList()}</Content>
                <Pagination
                  onChange={this.onPageNoChange}
                  onPageSizeChange={this.onPageSizeChange}
                  current={currentPage}
                  total={total}
                  pageSize={this.props.pageSize}
                />
              </>
            )}
          </BodyContent>
        </Body>
      </>
    );
  }
}

export default connect(
  (state) => ({
    ...state.project.projectPipeline,
    pageInfo: state.root.pageInfo,
    projectInfo: state.project.root.projectInfo,
  }),

  (dispatch) => bindActionCreators(actions, dispatch),
)(Root);
